package net.gz01.wallet.web.controller.customer;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import com.alibaba.druid.util.StringUtils;
import com.jfinal.aop.Clear;

import lombok.extern.slf4j.Slf4j;
import net.gz01.util.ZODate;
import net.gz01.util.ZOJson;
import net.gz01.util.ZOMD5;
import net.gz01.wallet.common.WalletSMS;
import net.gz01.wallet.message.AccountTransferResp;
import net.gz01.wallet.web.config.SystemConfig;
import net.gz01.wallet.web.config.SystemEnum;
import net.gz01.wallet.web.controller.BaseController;
import net.gz01.wallet.web.model.Account;
import net.gz01.wallet.web.model.MerchUser;
import net.gz01.wallet.web.model.TradeOrder;
import net.gz01.wallet.web.model.YouliAccount;
import net.gz01.wallet.web.noitfy.NotifyThread;
import net.gz01.wallet.web.service.AccountService;

@Slf4j
@Clear
public class CasherdeskController extends BaseController {
	private AccountService accountService = new AccountService();
	/**
	 * 展示收银台
	 * //@param id
	 * //@param mac
	 * //@param map
	 * @return
	 */
	public void index() {
		log.info("收银台接收到支付请求：" + getRequest().getParameterMap().toString());
		String orderNo = getPara("orderNo");
		String payType = getPara("payType");
		// 之前的流程已经创建了订单，除非BUG或人为错误调用，否则订单一定存在
		TradeOrder order = TradeOrder.dao.selectByOrderNo(orderNo);
		if (order == null) {
			renderText("订单不存在，单号=" + orderNo);
			return;
		}
		MerchUser xfzUser = null;
		MerchUser seller = null;

		//钱包支付
		if(!"1".equals(payType)) {
			xfzUser = MerchUser.dao.selectByMerCode(order.getMerchCode(), order.getPayer());//消费者
			getSession().setAttribute("loginMerchUser", xfzUser);
			seller = MerchUser.dao.selectByMerCode(order.getAccountNo());//商家
		}
		//线下转账
		else {
			xfzUser = MerchUser.dao.selectByMerCode(order.getBuyer());//消费者
			getSession().setAttribute("loginMerchUser", xfzUser);
			seller = MerchUser.dao.selectByMerCode(order.getMerchCode());//商家
		}
		setAttr("order", order);
		setAttr("buyer", xfzUser);
		setAttr("seller", seller);
		if(!"1".equals(payType)) {
			if (StringUtils.isEmpty(xfzUser.getPayPassword()) ||
					xfzUser.getPayPassword().equals(xfzUser.getPassword())) {
				setAttr("payPassword", "null");
				String payUrl = "/customer/casherdesk/index?orderNo=" + orderNo;
				redirect("/customer/index?api=api&payUrl=" + payUrl + "&login=" + xfzUser.getUserName() +
						"&loginType=" + xfzUser.getUserType());
				return;
			} else {
				setAttr("payPassword", "have");
			}
			Account account = Account.dao.select(xfzUser.getMerchCode());
			setAttr("buyerBlance", account.getBalanceShow());
			render("casherdesk.html");
		}else {//充值单
			if (SystemEnum.BizType.Charge.getValue().equals(order.getBizType())) {
				setAttr("youliAccount", YouliAccount.dao.findById(order.getYouliAccountId()));
			}
			render("chargedesk.html");
		}
	}

	/**
	 * 支付
	 * //@param id
	 * //@param mac
	 * //@param mm
	 * @return
	 */
	public void payment() {
		String orderNo = getPara("orderNo");
		TradeOrder order = TradeOrder.dao.selectByOrderNo(orderNo);
		TreeMap<String , String> treeMap = new TreeMap<>();
		treeMap.put("mallOrderNo", order.getOutOrderNo());
		treeMap.put("version", "V1.0");
		treeMap.put("timestamp", "" +System.currentTimeMillis());
		String respCode = "00";
		String respMsg = "成功";
		if(order.getOrderStatus()!=null && !SystemEnum.OrderStatus.InProcess.getValue().equals(order.getOrderStatus())){
			respCode = "01";
			respMsg = "请不要重复处理订单";
			treeMap.put("respCode", respCode);
			treeMap.put("respMsg", respMsg);
			String url = getReturnUrl(order.getReturnUrl(), treeMap);
			treeMap.put("url", url);
			//redirect(url);
			renderJson(treeMap);
			return;
		}
		MerchUser merchUser = MerchUser.dao.selectByMerCode(order.getMerchCode());
		getSession().setAttribute("loginMerchUser", merchUser);
		String payPassword = getPara("payPassword");
		//消费者
		if(merchUser==null){
			respCode = "01";
			respMsg = "消费者角色错误!!";
			treeMap.put("respCode", respCode);
			treeMap.put("respMsg", respMsg);
			String url = getReturnUrl(order.getReturnUrl(), treeMap);
			treeMap.put("url", url);
			//redirect(url);
			renderJson(treeMap);
			return;
		}

		if(!ZOMD5.codeFor(payPassword).equals(merchUser.getPayPassword())){
			respCode = "01";
			respMsg = "支付密码错误!";
			treeMap.put("respCode", respCode);
			treeMap.put("respMsg", respMsg);
			String url = getReturnUrl(order.getReturnUrl(), treeMap);
			treeMap.put("url", url);
			//redirect(url);
			renderJson(treeMap);
			return;
		}

		MerchUser merchSeller = MerchUser.dao.selectByMerCode(order.getAccountNo());
		if(merchSeller==null){
			respCode = "01";
			respMsg = "商家登录角色错误!";
			treeMap.put("respCode", respCode);
			treeMap.put("respMsg", respMsg);
			String url = getReturnUrl(order.getReturnUrl(), treeMap);
			treeMap.put("url", url);
			//redirect(url);
			renderJson(treeMap);
			return;
		}

		//消费者虚账减钱  //商家虚账加钱
		AccountTransferResp resp = accountService.transfer(order.getMerchCode(), order.getAccountNo(), Math.abs(order.getAmount()));
		log.info("订单:" + orderNo + ":钱包支付虚账结果-->" + ZOJson.toString(resp));
		if("SUCCESS".equals(resp.getRespCode())){
			order.setPurpose("");
			order.setPayTime(ZODate.getDateTime());
			order.setOrderStatus(SystemEnum.OrderStatus.Success.getValue());//钱包内支付不需要审核
			order.setRespMsg(resp.getRespMsg());
			order.setRespCode("00");
			order.setSettleDate(ZODate.getDate());
			order.setBalance(Long.parseLong(resp.getFromAccountBalance()));
			order.setAccountBalance(Long.parseLong(resp.getToAccountBalance()));
			order.update();
			treeMap.put("payTime", order.getPayTime());
			treeMap.put("respCode", "00");
			treeMap.put("respMsg", "成功");
			String url = getReturnUrl(order.getReturnUrl(), treeMap);

			TradeOrder inOrder = new TradeOrder();
			inOrder.createOrderPayIn(order, SystemEnum.BizType.ExpenseIn.getValue());//创建收入订单


			//开始异步回调线程
			NotifyThread.getInstance().addNotifyOrder(order);

			//redirect(url);//同步返回重定向过去
			treeMap.put("url", url);
			//redirect(url);
			renderJson(treeMap);

			//需要发送消费者手机钱包扣钱成功。
			WalletSMS.sendSMSSubMenoy(merchUser.getUserName(), Math.abs(order.getAmount()), Long.parseLong(resp.getFromAccountBalance()));

			//然后发送商家手机号，钱包入账金额成功。
			WalletSMS.sendSMSAddMenoy(merchSeller.getUserName(), Math.abs(order.getAmount()), Long.parseLong(resp.getToAccountBalance()));

		}else {
			treeMap.put("respCode", "01");
			treeMap.put("respMsg", "钱包账户余额不足");
			String url = getReturnUrl(order.getReturnUrl(), treeMap);
			//redirect(url);
			treeMap.put("url", url);
			//redirect(url);
			renderJson(treeMap);
		}
	}


	public void returnPay(){
		String orderNo = getPara("orderNo");
		TradeOrder order = TradeOrder.dao.selectByOrderNo(orderNo);
		TreeMap<String , String> treeMap = new TreeMap<>();
		treeMap.put("mallOrderNo", order.getOutOrderNo());
		treeMap.put("version", "V1.0");
		treeMap.put("timestamp", "" +System.currentTimeMillis());
		String respCode = "99";
		String respMsg = "等待打款处理...";

		MerchUser merchUser = MerchUser.dao.selectByMerCode(order.getMerchCode());
		getSession().setAttribute("loginMerchUser", merchUser);
		treeMap.put("respCode", respCode);
		treeMap.put("respMsg", respMsg);
		String url = getReturnUrl(order.getReturnUrl(), treeMap);
		treeMap.put("url", url);
		redirect(url);
		return;
	}

	public void setPayPassword(){
		String userName = getPara("userName");
		String payPassword1 = getPara("payPassword1");
		String payPassword2 = getPara("payPassword2");

		if(!payPassword1.equals(payPassword2)){
			setAttr("error", "两次密码不一致!");
			render("casherdesk.html");
			return;
		}

		MerchUser merchUser =  MerchUser.dao.selectByUserName(userName, "1");
		merchUser.setPayPassword(ZOMD5.codeFor(payPassword1));
		merchUser.update();


		log.info("收银台接收到支付请求：" + getRequest().getParameterMap().toString());
		String orderNo = getPara("orderNo");
		if(orderNo == null){
			log.info("收银台订单号错误：" + orderNo);
			return;
		}

		log.info("设置成功:" + userName + ":" + payPassword1 + "," + payPassword2);


		TradeOrder order = TradeOrder.dao.selectByOrderNo(orderNo);
//		MerchUser merchUser = MerchUser.dao.selectByUserName(order.getPayer());
		getSession().setAttribute("loginMerchUser", merchUser);

		MerchUser seller = MerchUser.dao.selectByMerCode(order.getMerchCode());
		setAttr("order", order);
		setAttr("buyer", merchUser);
		if(StringUtils.isEmpty(merchUser.getPayPassword()) ||
				merchUser.getPayPassword().equals(merchUser.getPassword())){
			setAttr("payPassword", "null");
		}else {
			setAttr("payPassword", "have");
		}
		Account account = Account.dao.select(merchUser.getMerchCode());
		setAttr("buyerBlance", account.getBalanceShow());
		setAttr("seller", seller);

		render("casherdesk.html");

	}



	private String getReturnUrl(String url, TreeMap<String, String> treeMap){
		String sign = ZOMD5.sortSign(treeMap, SystemConfig.config.get("apiyl_key"));
		treeMap.put("sign", sign);

		if(url.contains("?")){
			return url + "&" + getNamValStr(treeMap);
		}
		return  url+ "?" + getNamValStr(treeMap);
	}

	private  String getNamValStr(Map<String, String> map){
		StringBuilder str = new StringBuilder();
		Set<String> set = map.keySet();
		for (String key : set) {
			str.append(key).append("=").append(map.get(key).toString()).append("&");
		}
		return str.toString().substring(0, str.lastIndexOf("&"));
	}

}
